package com.lipaluma.field.validator.impl.Enum;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.lipaluma.annotations.validations.Validate;
import com.lipaluma.context.Context;
import com.lipaluma.exceptions.CsvParserException;
import com.lipaluma.field.validator.impl.generic.AbstractIsExcludedOfValidator;
import com.lipaluma.util.ParserUtils;
import com.lipaluma.util.ReflectionUtils;
import com.lipaluma.xml.validator.XmlExcludedOfValidator;
import com.lipaluma.xml.validator.XmlValidator;

/**
 * Validate a Enum field to check that the value of the field must be different compared with given values.<br/>
 * 
 * <p>
 * To Initialize :
 * <ul>
 * 	<li>
 * 	<u><b>By annotations :</b></u> Use {@link Validate}, with the attribute <code>excludedOf</code> 
 * to specify the list of values rejected. The given values must match with the values of the enum.<br/>
 * </li>
 * 	<li>
 * 	<u><b>By Xml :</b></u>
 * <ul>
 * This validator may be added using xml mapping with the element <code>excludedOf</code> like below : <br/>
 * <code>
 * &lt;ToMap field="..."   ...><br/>
 * <b>
 * &nbsp;&nbsp;&nbsp;&lt;excludedOf><br/>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value>VALUE_ENUM_1&lt;/value><br/>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value>VALUE_ENUM_2&lt;/value><br/>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value>VALUE_ENUM_3&lt;/value><br/>
 * &nbsp;&nbsp;&nbsp;&lt;/excludedOf><br/>
 * </b>
 * &lt;/ToMap>
 * </code>
 * </li>
 * </ul>
 * @author Mario
 *
 */
public class EnumExcludedOfValidator extends AbstractIsExcludedOfValidator<Enum<?>> {

	public EnumExcludedOfValidator() {}
	public EnumExcludedOfValidator(Enum<?>... values) {
		if(values == null)
			throw new CsvParserException("Error on setting "+this.getClass()+" : given values can't be null");
		init(Arrays.asList(values));		
	}

	@Override
	public boolean init(Context context, Field field) {
		Validate annotation = field.getAnnotation(Validate.class);
		if(annotation == null || annotation.excludedOf().length == 0)
			return false;
		
		List<Enum<?>> enums = new ArrayList<Enum<?>>();
		for (String string : annotation.excludedOf()) {
			enums.add(ParserUtils.parseToEnum(ReflectionUtils.getParameterizedClass(field), string));
		}
		init(enums);
		return true;
	}

	@Override
	public boolean init(Context context, Field field, XmlValidator xmlValidator) {
		XmlExcludedOfValidator validator = (XmlExcludedOfValidator) xmlValidator;
		List<Enum<?>> enums = new ArrayList<Enum<?>>();
		for (String value : validator.getValues()) {
			enums.add(ParserUtils.parseToEnum(ReflectionUtils.getParameterizedClass(field), value));
		}
		init(enums);
		return true;
	}

	
}
